package m.store.action;

import m.appserver.AuthInfoUtil;
import m.base.action.BaseStatusAction;
import m.base.action.GoodsInfoAction;
import m.base.model.GoodsInfo;
import m.base.model.StoreInfo;
import m.base.service.GoodsInfoService;
import m.base.util.LevelUtil;
import m.base.util.PowerUtil;
import m.base.util.ZolUtil;
import m.common.action.ActionMeta;
import m.common.action.RequestMeta;
import m.common.action.VueResult;
import m.common.model.util.*;
import m.html.VueFormResult;
import m.html.VueListResult;
import m.html.VueTabResult;
import m.html.element.Element;
import m.html.element.attr.Align;
import m.html.element.attr.ButtonType;
import m.html.element.other.Param;
import m.html.form.*;
import m.html.list.*;
import m.html.tab.TabItem;
import m.store.model.StoreGoods;
import m.store.model.StoreType;
import m.store.service.StoreGoodsService;
import m.store.util.ColorUtil;
import m.system.cache.CacheUtil;
import m.system.db.TransactionManager;
import m.system.exception.MException;
import m.system.util.JSONMessage;
import m.system.util.ObjectUtil;
import m.system.util.StringUtil;
import manage.model.StatusModel;

import java.util.List;

@ActionMeta(name = "store/storeGoods")
public class StoreGoodsAction extends BaseStatusAction {
    private StoreGoods model;

    @RequestMeta(logTitle = "商户商品",logDescription = "保存商户商品报价信息")
    public JSONMessage doSaveOfferPrice() throws Exception {
        log("商户商品","保存商户商品报价");
        PowerUtil.verifyStoreData(model.getStore().getOid());
        ModelQueryCheck.init(model)
            .checkNotNull("offerPrice","请输入报价")
            .checkNumberRange("offerPrice",0D,999999999D,"报价不能小于0")
            .checkNotNull("storeType.oid","请选择商品分类")
            .doCheck(false,true);
        ModelUpdateUtil.updateModel(model,"offerPrice","storeType.oid");
        return new JSONMessage(0,"修改成功");
    }
    public VueResult toEditOfferPrice() throws Exception {
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            model= ModelQueryList.getModel(model,"*","storeType.*");
        }else{
            throw new MException(this.getClass(),"参数错误");
        }
        ModelForm form = new ModelForm("商品报价",2);
        form.addItem(
            FormHtml.inputStyle("商品名称", "{{model.factoryName}} <a-typography-link @click=\"viewGoods\">{{model.name}}</a-typography-link>").setSpan(2),
            FormHtml.inputStyle("剩余数量", "{{formatNumber(model.surplusNum,'#,##0')}}"),
            FormHtml.inputStyle("剩余金额", "{{formatNumber(model.surplusAmount,'#,##0.00')}}元"),
            FormHtml.inputStyle("商品类型","{{model.type.parent.name}} - {{model.typeName}}"),
            FormHtml.inputStyle("平均单价", "{{formatNumber(model.surplusPrice,'#,##0.00')}}元"),
            FormInput.selectItem("商品分类","model.storeType.oid","m.store.model.StoreType:"+PowerUtil.getSessionStoreOid()).setPlaceholder("请选择商品分类").setRequired(true),
            FormInput.number("报价","model.offerPrice").setPlaceholder("请输入报价").setRequired(true)
        )
        .addData("model",model)
        .addButton(
            FormButton.pri("保存报价","doSaveOfferPrice")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.doJson("doSaveOfferPrice",actionUrl("doSaveOfferPrice"),"{model:this.model}")
                    .success("backFlag"),
            FormEvent.toModal("viewGoods","page/store/storeGoods.js","{oid:this.model.oid}",700)
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form)
            .addForm(new CustomForm(Element.tag("a-alert").A("message","商品分类和报价用于报价单模块，不使用报价单功能的无需配置。")));
    }
    @RequestMeta(params = {"goodsOid"})
    public VueResult toRecord(String goodsOid){
        JSONMessage p=new JSONMessage();
        p.push("params",new JSONMessage().push("goodsOid",goodsOid));
        VueTabResult tab=new VueTabResult("商品记录");
        tab.addItems(new TabItem("stockRecord","入库记录",actionUrl(GoodsStockRecordAction.class,"goodsRecordList"),p));
        tab.addItems(new TabItem("outRecord","出库记录",actionUrl(GoodsOutRecordAction.class,"goodsRecordList"),p));
        return tab;
    }
    public VueResult toView() throws Exception {
        if(null!=model&&!StringUtil.isSpace(model.getOid())){
            model= ModelQueryList.getModel(model,"*","storeType.name");
        }else{
            throw new MException(this.getClass(),"参数错误");
        }
        ModelForm form = new ModelForm("商品进销存",3);
        form.setSubTitle("{{model.factoryName}}");
        form.addItem(
            FormHtml.inputStyle("商品名称", "<a-typography-link @click=\"viewGoods\">{{model.name}}</a-typography-link> / {{model.storeType.name}} {{model.typeName}}").setSpan(2),
            FormHtml.inputStyle("盈利金额", "{{formatNumber(model.gainAmount,'#,##0.00')}}元"),
            FormHtml.inputStyle("入库数量", "{{formatNumber(model.stockNum,'#,##0')}} / {{formatNumber(model.stockAmount,'#,##0.00')}}元"),
            FormHtml.inputStyle("出库数量", "{{formatNumber(model.saleNum,'#,##0')}} / {{formatNumber(model.saleAmount,'#,##0.00')}}元"),
            FormHtml.inputStyle("剩余数量", "{{formatNumber(model.surplusNum,'#,##0')}} / {{formatNumber(model.surplusAmount,'#,##0.00')}}元")
        )
        .addData("model",model)
        .addMethod(
            FormEvent.toModal("viewGoods","page/store/storeGoods.js","{oid:this.model.oid}",700)
        );
        LoadPage form1=new LoadPage("goodsRecordTab",actionUrl("toRecord"),"{goodsOid:this.model.oid}");
        form1.setMounted("this.goodsRecordTab();");
        VueFormResult result=new VueFormResult();
        return result.addForm(form).addForm(form1);
    }
    @RequestMeta(params = {"oid"})
    public JSONMessage get(String oid) throws Exception {
        StoreGoods model=ModelQueryList.getModel(StoreGoods.class,oid,"*");
        if(ObjectUtil.isEmptyOid(model)) throw new MException(this.getClass(),"商品不存在");
        PowerUtil.verifyStoreData(model.getStore().getOid());
        return new JSONMessage(0)
            .push("model",model);
    }
    @RequestMeta(transaction = true,logTitle = "商户商品",logDescription = "保存商户商品信息")
    public JSONMessage doSave() throws Exception {
        String msg=getService(StoreGoodsService.class).doSave(model);
        return new JSONMessage(0,msg);
    }
    @RequestMeta(params = {"goodsUrl"})
    public JSONMessage doSaveLink(String goodsUrl) throws Exception {
        StoreInfo store=PowerUtil.getSessionStore();
        if(null==store) throw AuthInfoUtil.noPowerException;
        String[] goodsUrls=goodsUrl.split("\n");
        int num=0;
        for(String gu : goodsUrls) {
            TransactionManager tm=new TransactionManager();
            try {
                tm.begin();
                GoodsInfo model = getService(GoodsInfoService.class).doSave(ZolUtil.getOutId(gu));
                if(!StatusModel.Status_Enable.equals(model.getStatus())) {//不是启用状态再次采集
                    model = getService(GoodsInfoService.class).doCollection(model.getOid());
                }
                getService(StoreGoodsService.class).copyGoodsInfo(store,model);
                tm.commit();
                num++;
            }catch (Exception e){
                tm.rollback();
            }
        }
        return new JSONMessage(0,"成功采集了"+num+"条!");
    }
    public VueResult toCollection(){
        ModelForm form = new ModelForm("商品采集",1);
        form.addItem(
            FormInput.textarea("商品参数页面","goodsUrl").setPlaceholder("请输入商品url地址")
        )
        .addData("goodsUrl","")
        .addButton(
            FormButton.gho("转换url","convertGoodsUrl"),
            FormButton.pri("保存并采集","doSaveLink")
        )
        .addMethod(
            FormEvent.backFlag,
            FormEvent.toModal("convertGoodsUrl",actionUrl(GoodsInfoAction.class,"convertGoodsUrl"),"{}",800)
                .fillData("goodsUrl"),
            FormEvent.doJson("doSaveLink",actionUrl("doSaveLink"),"{goodsUrl:this.goodsUrl}")
                .success("backFlag")
        );
        VueFormResult result=new VueFormResult();
        return result.addForm(form)
            .addForm(new CustomForm("提醒",false)
                .addElement(
                    Element.tag("a-alert").A("message","提醒").A("show-icon")
                    .E(
                        Element.tag("template").A("#description")
                        .E(
                            Element.tag("div").E("批量采集：每一行输入一个商品url")
                        )
                    )
                )
            );
    }
    private ListColumn getPropertyColumn(){
        String dict="m.store.model.StoreGoods!property";
        return toElementColumn("性质", "property", 100,
                ListElement.tag(dict, ColorUtil.getGoodsProperty(),false)
        ).setAlign(Align.CENTER).setFilter(true).setDictType(dict);
    }
    /*
     * 商户商品管理列表
     */
    public VueResult storeGoodsList() throws Exception {
        boolean edit="edit".equals(getParamsValue("oper","view"));
        boolean power=PowerUtil.hasPower(PowerUtil.Store);
        VueListResult result=getVueListResult("商品信息",StoreGoods.class,actionUrl("storeGoodsList"));
        result.setSubTitle("商品信息列表");
        result.setFunction(LevelUtil.exportFunc(),false);
        result.setHeight(-1);
        result.addQueryFields("goods.oid");
        result.addCol(toIndexColumn());
        result.addCol(getPropertyColumn().setFixed(Align.LEFT));
        result.addCol(toLinkColumn("商品名称", "name", 250, true,
            new ListEvent(actionUrl("toView"), EventType.MODAL,1200)
                .addParam("model.oid","oid")
        ).setFixed(Align.LEFT));
        result.addCol(toTextColumn("商品类型", "typeName", 100, true));
        result.addCol(toTextColumn("商品厂商", "factoryName", 100, true));
        result.addCol(toTextColumn("商品分类", "storeType.oid", 100, true).setDictType(StoreType.class,PowerUtil.getSessionStoreOid()));
        result.addCol(toNumberColumn("报价","offerPrice",100,true));
        result.addCol(toStatusColumn(power&&edit, true).setDictType("m.store.model.StoreGoods!status"));
        result.addCol(toNumberColumn("均价", "surplusPrice", 100, true).setGroupTitle("剩余").setCount(ListCount.NONE));
        result.addCol(toIntegerColumn("数量", "surplusNum", 100, true).setGroupTitle("剩余"));
        result.addCol(toNumberColumn("金额", "surplusAmount", 100, true).setGroupTitle("剩余"));
        result.addCol(toIntegerColumn("数量", "stockNum", 100, true).setGroupTitle("入库"));
        result.addCol(toNumberColumn("金额", "stockAmount", 100, true).setGroupTitle("入库"));
        result.addCol(toIntegerColumn("数量", "saleNum", 100, true).setGroupTitle("出库"));
        result.addCol(toNumberColumn("金额", "saleAmount", 100, true).setGroupTitle("出库"));
        result.addCol(toNumberColumn("盈利金额", "gainAmount", 100, true));
        if(edit) {
            result.addCol(toSpaceColumn("操作", 130,
                ListElement.test("!record.goods.oid",
                    ListButton.modal("修改", ButtonType.PRIMARY, "page/store/storeGoods.js", 700, SuccessMethod.REFRESH)
                        .addParam("oid", "oid").addQueryParam(Param.value("oper", "edit"))
                        .addQueryParam(Param.value("storeOid", PowerUtil.getSessionStoreOid()))
                ),
                ListButton.drawer("报价", ButtonType.DEFAULT, actionUrl("toEditOfferPrice"), 600, SuccessMethod.REFRESH).addParam("model.oid", "oid")
            ).setFixed(Align.RIGHT));
            result.addButton(
                ListButton.modal("新增商品", ButtonType.PRIMARY, "page/store/storeGoods.js", 700, SuccessMethod.REFRESH)
                    .addQueryParam(Param.value("storeOid", PowerUtil.getSessionStoreOid()))
                    .addQueryParam(Param.value("oper", "edit"))
            );
//            result.addButton(
//                ListButton.modal("采集商品", ButtonType.GHOST, actionUrl("toCollection"), 700, SuccessMethod.REFRESH)
//            );
            result.addButton(
                ListButton.importExcel("导入外部商品", ButtonType.GHOST, "action/store/storeGoodsZol")
            );
        }
        //排序 result.addOrder
        //查询条件 result.addCondition
        result.addCondition(QueryCondition.eq("store.oid",PowerUtil.getSessionStoreOid()));
        return result;
    }
    public VueResult selectOneStoreGoods() throws Exception {
        String selected=getParamsValue("selected","");
        VueListResult result=getVueListResult("选择商品",StoreGoods.class,actionUrl("selectOneStoreGoods"));
        result.setSubTitle("商品信息列表");
        result.setFunction(LevelUtil.exportFunc(),false);
        result.setHeight(-1);
        result.addCol(toIndexColumn());
        result.setMergeCellsInfo(1,3);
        result.addCol(toTextColumn("商品分类", "storeType.oid", 100, true).setDictType(StoreType.class,PowerUtil.getSessionStoreOid()));
        result.addCol(toTextColumn("商品类型", "typeName", 100, true));
        result.addCol(toTextColumn("商品厂商", "factoryName", 100, true));
        result.addCol(toLinkColumn("商品名称", "name", 250, true,
                new ListEvent(actionUrl("toView"), EventType.MODAL,1200)
                        .addParam("model.oid","oid")
        ));
        result.addCol(toNumberColumn("报价","offerPrice",100,true));
        result.addCol(toNumberColumn("均价", "surplusPrice", 100, true).setGroupTitle("剩余"));
        result.addCol(toIntegerColumn("数量", "surplusNum", 100, true).setGroupTitle("剩余"));
        result.addCol(toNumberColumn("金额", "surplusAmount", 100, true).setGroupTitle("剩余"));
        result.addCol(toSpaceColumn("操作", 100,
            ListElement.test("record.oid!='"+selected+"'",
                ListButton.back("选择", ButtonType.PRIMARY)
                    .addParam("","")
            ),
            ListElement.elseOther(ListElement.tag("已选",""))
        ).setFixed(Align.RIGHT));
        //排序 result.addOrder
        //查询条件 result.addCondition
        result.addCondition(QueryCondition.eq("store.oid",PowerUtil.getSessionStoreOid()));
        result.addCondition(QueryCondition.eq("status",StatusModel.Status_Enable));
        result.addCondition(QueryCondition.eq("property",StoreGoods.Property_Goods));
        result.addOrder(
            QueryOrder.asc("storeType.oid"),
            QueryOrder.asc("typeName"),
            QueryOrder.asc("factoryName")
        );
        return result;
    }
    /*
     * 商户商品维护
     */
    public VueResult myManageList() throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);
        VueListResult result=getVueListResult("自建商品导入维护",StoreGoods.class,actionUrl("myManageList"));
        result.setSubTitle("通过导出修改再导入，快速维护商品信息。");
        result.setFunction(true,false);
        result.setHeight(-1);
        result.addCol(toTextColumn("商品类型", "typeName", 100, true));
        result.addCol(toTextColumn("商品厂商", "factoryName", 100, true));
        result.addCol(toTextColumn("商品名称", "name", 250, true));
        result.addCol(toTextColumn("商品分类", "storeType.oid", 100, true).setDictType(StoreType.class,PowerUtil.getSessionStoreOid()));
        result.addCol(toNumberColumn("报价","offerPrice",100,true).setCount(ListCount.NONE));
        //排序 result.addOrder
        //查询条件 result.addCondition
        result.addCondition(QueryCondition.eq("store.oid",PowerUtil.getSessionStoreOid()));
        result.addCondition(QueryCondition.isEmpty("goods.oid"));
        result.addButton(
            ListButton.importExcel("导入自建商品", ButtonType.GHOST, "action/store/storeGoods")
        );
        return result;
    }
    @Override
    protected JSONMessage processImportSetting(String importParam) {
        return new JSONMessage()
            .push("alertMessage","导入模板在列表左下角导出，商品名称重复则会覆盖原商品信息。")
            .push("canStop",true);
    }
    @Override
    protected String processImportData(List<String[]> data, String importParam) throws Exception {
        PowerUtil.verifyPower(PowerUtil.Store);
        setImportCurrentTitle("正在处理商品信息");
        String msg;
        TransactionManager tm=new TransactionManager();
        try{
            tm.begin();
            int n=0;
            StringBuffer error=new StringBuffer();
            setImportCountNum(data.size());
            for(int i=0;i<data.size();i++) {//循环数据，已排除第一行
                setImportCurrentNum(i);
                if(isStopImport()) throw new MException(this.getClass(),"用户中止导入\r\n"+error);
                String[] arr=parseRowData(data.get(i),5);//获取每行数据
                if(!StringUtil.isSpace(arr[0])){
                    int row=i+2;
                    try{
                        StoreType type=null;
                        if(StringUtil.notSpace(arr[3])) {
                            type = ModelQueryList.getModel(StoreType.class, new String[]{"*"},
                                QueryCondition.and(
                                    QueryCondition.eq("name", arr[3]),
                                    QueryCondition.eq("store.oid", PowerUtil.getSessionStoreOid())
                                )
                            );
                            if (null == type) throw new MException(this.getClass(), arr[3] + " 分类不存在");
                        }
                        StoreGoods goods=ModelQueryList.getModel(StoreGoods.class,new String[]{"*"},
                            QueryCondition.and(
                                QueryCondition.eq("name",arr[2]),
                                QueryCondition.eq("store.oid",PowerUtil.getSessionStoreOid())
                            )
                        );
                        if(null==goods){
                            goods=new StoreGoods();
                        }
                        goods.setTypeName(arr[0]);
                        goods.setFactoryName(arr[1]);
                        goods.setName(arr[2]);
                        goods.setStoreType(type);
                        goods.setOfferPrice(parseDouble(arr[4],row,"报价",error));
                        getService(StoreGoodsService.class).doSave(goods);
                        n++;
                    }catch(Exception e){
                        error.append("\r\n第").append(row).append("行!").append(e.getMessage());
                        setImportMessage(error.toString());
                    }
                }
            }
            if(error.length()>0){
                throw new MException(this.getClass(),error.toString());
            }
            msg="上传了"+data.size()+"条，成功导入了"+n+"条";
            tm.commit();
        }catch (Exception e){
            tm.rollback();
            throw e;
        }
        return msg;
    }

    @Override
    public StoreGoods getModel() {
        return model;
    }

    @Override
    public String[] getStatusPower() {
        return new String[0];
    }

    public void setModel(StoreGoods model) {
        this.model = model;
    }
}
